import Component from "../Component.js";
import Type from "../../experience/db/Type.js";
const Draw = ol.interaction.Draw;
const Snap = ol.interaction.Snap;
const LineString = ol.geom.LineString;

export default class Position extends Component{
    constructor() {
        super();

        this.init();
        this.status = true;
    }

    init() {
        this.source = this.drawer.source(Type.Track);
        this.source2 = this.drawer.source(Type.Modify);
        this.draw = new Draw({ source: this.source2, type: 'Point' });
        this.snap = new Snap({ source: this.source });
    }

    start() {
        this.init();
        this.drawer.addInteraction(this.draw);
        this.drawer.addInteraction(this.snap);
        this.drawer.source(Type.Modify).clear();
        this.$$("#position-cancel").show();
    }

    drag(nodeId) {
        this.toast(`请将编号为 ${nodeId} 的分站放置到轨迹线上。`);

        // 启动描画和捕捉器
        this.start();
        this.draw.on('drawend', (event) => {
            let isInline = false
            const point = event.feature.getGeometry().getCoordinates();
            this.source.getFeatures().forEach(async feature => {
                const track = feature.getGeometry().getCoordinates();
                isInline = feature.getGeometry().intersectsCoordinate(point);
                if (isInline === true) {
                    const track_id = feature.getId();
                    this.track(point, track);
                    await this.update(nodeId, point, track_id, track);
                    this.$$("#position-cancel").hide();
                    return feature;
                }
            });

            // 定位卡坐标没有在轨迹线上
            if (isInline === false) {
                this.drawer.source(Type.Modify).clear();
                this.toast("请将分站放置在轨迹线上。");
            }
        });
    }

    cancel() {
        this.status = true;
        this.emitter.emit("cancel-selected");
        this.drawer.removeInteraction(this.snap);
        this.drawer.removeInteraction(this.draw);
        this.drawer.source(Type.Modify).clear();
    }

    track(point, track) {
        for (let i = 0; i < track.length - 1; i++) {
            const line = new LineString([track[i], track[i+1]]);
            if (line.intersectsCoordinate(point)) {
                track.splice(i + 1, 0, point);
                break;
            }
        }

        track.forEach((item) => {
            item[0] = this.algo.denormalX(item[0]);
            item[1] = this.algo.denormalY(item[1]);
        });
    }

    async update(node_id, point, track_id, track) {
        const mode = this.utils.getLocalStorage("mode");
        const config = this.algo.getConfig();
        const params = {
            meta_id: config.meta_id, type: mode,
            node_id: node_id, point: point,
            track_id: track_id, track: track
        };

        const data = await this.api.addPosition(params);
        if (data.code === 0) {
            await this.db.refresh(Type.Position, data.data.positions);
            await this.drawer.draw(Type.Position);
            await this.db.refresh(Type.Track, data.data.tracks);
            await this.drawer.draw(Type.Track);
            this.cancel();
        }
    }

    template() {
        const station_popup_div = `
            <div class="popup station-popup" style="width: 300px; height: 220px;">
                <header>增加分站</header>
                <article>
                    <div class="list inline-labels no-hairlines-md">
                        <ul>
                            <li class="item-content item-input">
                                <div class="item-title item-label">分站卡号</div>
                                <div class="item-inner">
                                    <div class="item-input-wrap">
                                        <label for="station-code">
                                            <input type="text" id="station-code" placeholder="编号范围: 1-1000">
                                        </label>
                                    </div>
                                </div>
                            </li>
                            <li class="item-content item-input">
                                <div class="item-title item-label">分站类型</div>
                                <div class="item-inner">
                                    <div class="item-input-wrap">
                                        <label for="station-type">
                                            <select id="station-type">
                                                <option value="all">全部</option>
                                                <option value="vehicle">两方向车辆定位分站</option>
                                                <option value="person">两方向人员定位分站</option>
                                            </select>
                                        </label>
                                    </div>
                                </div>
                            </li>
                        </ul>
                    </div>
                </article>
                <footer>
                    <button class="button button-fill color-orange popup-close" id="station-popup-submit">确定</button>
                    <button class="button button-fill color-gray popup-close">取消</button>
                </footer>
            </div>
        `;
        this.$$('#app').append(station_popup_div);

        const pannel_div = `
            <div class="page" id="pannel" style="top: 60px; width: 20vw; height: 90vh;">
                <div class="page-title">
                    <span id="vl-title">轨迹回放</span>
                    <div class="page-cheked">
                        <i class="iconfont" style="font-size: 22px;" id="pannel-close">&#xe6ba;</i>
                    </div>
                </div>
                <div class="page-content"></div>
            </div>
        `;
        this.$$("#article").append(pannel_div);
        this.$$("#pannel").hide();
        this.$$("#position-cancel").hide();
    }

    control() {
        // 接收选择器发送过来的消息
        this.emitter.on("position-edited", async () => {
            this.emitter.locked = true;

            const feature = this.emitter.params[0], self = this;
            const id = feature.getId(), node_id = feature.get("node_id");
            const dialog = this.app.dialog.create({
                title: "选择分站操作",
                buttons: [
                    {
                        text: "删除",
                        onClick: async () => {
                            self.app.dialog.confirm('确认将服务器的数据删除?', async () => {
                                const config = this.algo.getConfig();
                                const data = await this.api.delPosition({
                                    id: id, meta_id: config.meta_id
                                });
                                if (data.code === 0) {
                                    await this.db.refresh(Type.Position, data.data);
                                    await this.drawer.draw(Type.Position);
                                }
                                this.emitter.locked = false;
                            }, () => {
                                this.emitter.emit("cancel-selected");
                                this.emitter.locked = false;
                            });
                        }
                    }, {
                        text: "移动",
                        onClick: async () => {
                            // 启动描画和捕捉器
                            this.start();

                            // 重新绘制分站位置
                            this.draw.on('drawend', (event) => {
                                let isInline = false
                                const point = event.feature.getGeometry().getCoordinates();
                                this.source.getFeatures().forEach(async feature => {
                                    const track = feature.getGeometry().getCoordinates();
                                    isInline = feature.getGeometry().intersectsCoordinate(point);
                                    if (isInline === true) {
                                        const track_id = feature.getId();
                                        this.track(point, track);
                                        await this.update(node_id, point, track_id, track);
                                        this.$$("#position-cancel").hide();
                                        this.emitter.locked = false;
                                        return feature;
                                    }
                                });

                                // 定位卡坐标没有在轨迹线上
                                if (isInline === false) {
                                    this.drawer.source(Type.Modify).clear();
                                    this.toast("请将分站放置在轨迹线上。");
                                }
                            });
                        }
                    }, {
                        text: "取消",
                        onClick: () => {
                            this.emitter.emit("cancel-selected");
                            this.emitter.locked = false;
                            dialog.close();
                        }
                    }
                ],
                verticalButtons: false
            }).open();
        });

        this.emitter.on("emit-position-drag", async () => {
            const readers = [], nodeIds = [];
            const features = this.drawer.source(Type.Position).getFeatures();
            features.forEach(feature => nodeIds.push(feature.get("node_id")));

            const resp = await this.api.getReaders();
            for (const reader of resp.data) {
                reader.isOnMap = nodeIds.includes(reader.readerid);
                readers.push(reader);
            }
            this.emitter.emit("emit-position-drag-response", resp.data);
        });

        this.emitter.on("emit-position-drag-id",() => {
            const nodeId = this.emitter.params[0];
            this.drag(nodeId);
        });

        // 添加分站事件
        this.$$("#position-add").on("click", () => {
            this.toast('请在地图上添加一个点代表定位卡,点击Esc取消本次添加。');

            // 启动描画和捕捉器
            this.start();

            // 重新绘制分站位置
            this.draw.on('drawend', (event) => {
                let isInline = false
                const point = event.feature.getGeometry().getCoordinates();
                this.source.getFeatures().forEach((feature) => {
                    const track = feature.getGeometry().getCoordinates();
                    isInline = feature.getGeometry().intersectsCoordinate(point);
                    if (isInline === true) {
                        const track_id = feature.getId();
                        this.track(point, track);
                        const dialog = this.app.dialog.prompt("请输入定位卡编号?", async (code) => {
                            const node_id = parseInt(code);
                            if (code === "" || isNaN(node_id) || node_id < 0 || node_id > 1000) {
                                this.toast("编号为小于1000的正整数.");
                                return;
                            }
                            await this.update(node_id, point, track_id, track);
                            this.$$("#position-cancel").hide();
                            return feature;
                        }, () => {
                            this.cancel();
                            this.$$("#position-cancel").hide();
                            dialog.close();
                        });
                    }
                });

                // 定位卡坐标没有在轨迹线上
                if (isInline === false) {
                    this.drawer.source(Type.Modify).clear();
                    this.toast("请将分站放置在轨迹线上。");
                }
            });
        });

        // 拖拽分站到地图上
        this.$$("#position-drag").on("click", async () => {
            this.$$("#vl-title").html("分站列表");
            this.$$("#pannel").show();
            this.toast("点击列表选择分站,将分站移动到轨迹线上。");
            this.$$("#pannel .page-content").empty();
            const div = `<div class="block"><div class="list simple-list"><ul></ul></div></div>`;
            this.$$("#pannel .page-content").append(div);

            const nodeIds = [];
            const features = this.drawer.source(Type.Position).getFeatures();
            features.forEach(feature => nodeIds.push(feature.get("node_id")));

            const resp = await this.api.getReaders();
            for (const reader of resp.data) {
                const id = `positon-${reader.readerid}`;

                let regname, li;
                if (reader.regname.length > 14) {
                    regname = reader.regname.substring(0, 14) + "...";
                } else {
                    regname = reader.regname;
                }

                if (nodeIds.includes(reader.readerid)) {
                    li = `
                        <li style="font-size: var(--table-row-font-size); cursor: pointer;" id=${id}>
                            <span>${reader.readerid} - ${regname}</span>
                            <span class="icon iconfont" style="color: green; font-size: 28px;">&#xe728;</span>
                        </li>
                    `;
                } else {
                    li = `
                        <li style="font-size: var(--table-row-font-size); cursor: pointer;" id=${id}>
                            <span>${reader.readerid} - ${regname}</span>
                            <span class="icon iconfont" style="color: red; font-size: 28px;">&#xe6f3;</span>
                        </li>
                    `;
                }

                this.$$("#pannel ul").append(li);
                this.$$(`#${id}`).on("click", () => {
                    this.$$("#pannel").hide();
                    this.drag(parseInt(id.split("-")[1]));
                });
            }
        });

        // 取消编辑
        this.$$("#position-cancel").on("click", async () => {
            this.cancel();
            this.$$("#position-cancel").hide();
        });

        // 关闭pannel
        this.$$("#pannel-close").on("click", async () => {
            this.$$("#pannel").hide();
        });
    }
}